// #pragma once

// #include <iostream>
// #include <string>
// #include <cerrno>
// #include <cstring>
// #include <cstdlib>
// #include <sys/types.h>
// #include <sys/socket.h>
// #include <netinet/in.h>
// #include <arpa/inet.h>
// #include "Log.hpp"
// #include "nocopy.hpp"
// #include "Comm.hpp"

// const static int default_backlog = 5; // TODO

// class TcpServer : public nocopy
// {
// public:
//     TcpServer(uint16_t port) : _port(port), _isrunning(false)
//     {
//     }
//     // 都是固定套路
//     void Init()
//     {
//         // 1. 创建socket, file fd, 本质是文件
//         _listensock = socket(AF_INET, SOCK_STREAM, 0);
//         if (_listensock < 0)
//         {
//             lg.LogMessage(Fatal, "create socket error, errno code: %d, error string: %s\n", errno, strerror(errno));
//             exit(Fatal);
//         }
//         lg.LogMessage(Debug, "create socket success, sockfd: %d\n", _listensock);

//         // 2. 填充本地网络信息并bind
//         struct sockaddr_in local;
//         memset(&local, 0, sizeof(local));
//         local.sin_family = AF_INET;
//         local.sin_port = htons(_port);
//         local.sin_addr.s_addr = htonl(INADDR_ANY);

//         // 2.1 bind
//         if (bind(_listensock, CONV(&local), sizeof(local)) != 0)
//         {
//             lg.LogMessage(Fatal, "bind socket error, errno code: %d, error string: %s\n", errno, strerror(errno));
//             exit(Bind_Err);
//         }
//         lg.LogMessage(Debug, "bind socket success, sockfd: %d\n", _listensock);

//         // 3. 设置socket为监听状态，tcp特有的
//         if (listen(_listensock, default_backlog) != 0)
//         {
//             lg.LogMessage(Fatal, "listen socket error, errno code: %d, error string: %s\n", errno, strerror(errno));
//             exit(Listen_Err);
//         }
//         lg.LogMessage(Debug, "listen socket success, sockfd: %d\n", _listensock);
//     }
//     // Tcp 连接全双工通信的.
//     void Service(int sockfd)
//     {
//         char buffer[1024];
//         // 一直进行IO
//         while (true)
//         {
//             ssize_t n = read(sockfd, buffer, sizeof(buffer) - 1);
//             if (n > 0)
//             {
//                 buffer[n] = 0;
//                 std::cout << "client say# " << buffer << std::endl;

//                 std::string echo_string = "server echo# ";
//                 echo_string += buffer;
//                 write(sockfd, echo_string.c_str(), echo_string.size());
//             }
//             else if (n == 0) // read如果返回值是0，表示读到了文件结尾(对端关闭了连接！)
//             {
//                 lg.LogMessage(Info, "client quit...\n");
//                 break;
//             }
//             else
//             {
//                 lg.LogMessage(Error, "read socket error, errno code: %d, error string: %s\n", errno, strerror(errno));
//                 break;
//             }
//         }
//     }
//     void Start()
//     {
//         _isrunning = true;
//         while (_isrunning)
//         {
//             // 4. 获取连接
//             struct sockaddr_in peer;
//             socklen_t len = sizeof(peer);
//             int sockfd = accept(_listensock, CONV(&peer), &len);
//             if (sockfd < 0)
//             {
//                 lg.LogMessage(Warning, "accept socket error, errno code: %d, error string: %s\n", errno, strerror(errno));
//                 continue;
//             }
//             lg.LogMessage(Debug, "accept success, get n new sockfd: %d\n", sockfd);

//             // 5. 提供服务啊, v1~v4
//             // v1
//             Service(sockfd);
//             close(sockfd);
//         }
//     }
//     ~TcpServer()
//     {
//     }

// private:
//     uint16_t _port;
//     int _listensock; // TODO
//     bool _isrunning;
// };


























// #include <iostream>
// #include <string>
// #include <cstring>
// #include <cstdlib>
// #include <unistd.h>
// #include <sys/types.h>
// #include <sys/socket.h>
// #include <netinet/in.h>
// #include <arpa/inet.h>
// #include "Comm.hpp"

// using namespace std;

// void Usage(const std::string &process)
// {
//     std::cout << "Usage: " << process << " server_ip server_port" << std::endl;
// }

// // ./tcp_client serverip serverport
// int main(int argc, char *argv[])
// {
//     if (argc != 3)
//     {
//         Usage(argv[0]);
//         return 1;
//     }
//     std::string serverip = argv[1];
//     uint16_t serverport = stoi(argv[2]);

//     // 1. 创建socket
//     int sockfd = socket(AF_INET, SOCK_STREAM, 0);
//     if(sockfd < 0)
//     {
//         cerr << "socket error" << endl;
//         return 1;
//     }

//     // 2. 要不要bind？必须要有Ip和Port, 需要bind，但是不需要用户显示的bind，client系统随机端口
//     // 发起连接的时候，client会被OS自动进行本地绑定
//     // 2. connect
//     struct sockaddr_in server;
//     memset(&server, 0, sizeof(server));
//     server.sin_family = AF_INET;
//     server.sin_port = htons(serverport);
//     // p:process(进程), n(网络) -- 不太准确，但是好记忆
//     inet_pton(AF_INET, serverip.c_str(), &server.sin_addr); // 1. 字符串ip->4字节IP 2. 网络序列

//     int n = connect(sockfd, CONV(&server), sizeof(server)); // 自动进行bind哦！
//     if(n < 0)
//     {
//         cerr << "connect error" << endl;
//         return 2;
//     }

//     // 并没有向server一样，产生新的sockfd.未来我们就用connect成功的sockfd进行通信即可.
//     while(true)
//     {
//         string inbuffer;
//         cout << "Please Enter# ";
//         getline(cin, inbuffer);

//         ssize_t n = write(sockfd, inbuffer.c_str(), inbuffer.size());
//         if(n > 0)
//         {
//             char buffer[1024];
//             ssize_t m = read(sockfd, buffer, sizeof(buffer)-1);
//             if(m > 0)
//             {
//                 buffer[m] = 0;
//                 cout << "get a echo messsge -> " << buffer << endl;
//             }
//             else if(m == 0 || m < 0)
//             {
//                 break;
//             }
//         }
//         else
//         {
//             break;
//         }
//     }

//     close(sockfd);
//     return 0;
// }